package smtpserver

import (
	"bufio"
	"context"
	"fmt"
	"net"
	"sync"

	"github.com/nosch/smtpoll/logger"
)

// BaseServer 基础服务器实现
type BaseServer struct {
	options  *ServerOptions
	handler  MessageHandler
	listener net.Listener
	wg       sync.WaitGroup
}

// NewBaseServer 创建新的基础服务器
func NewBaseServer(options *ServerOptions, handler MessageHandler) *BaseServer {
	return &BaseServer{
		options: options,
		handler: handler,
	}
}

// Run 运行服务器
func (s *BaseServer) Run() error {
	// 为每个端口创建监听器
	for _, port := range s.options.Ports {
		addr := fmt.Sprintf("%s:%d", s.options.Host, port)
		listener, err := net.Listen("tcp", addr)
		if err != nil {
			return fmt.Errorf("failed to listen on %s: %v", addr, err)
		}
		s.listener = listener

		logger.LogInfo(context.Background(), "SMTP server listening", "addr", addr)

		go func() {
			for {
				conn, err := listener.Accept()
				if err != nil {
					logger.LogError(context.Background(), "Error accepting connection", "addr", addr, "error", err)
					continue
				}

				s.wg.Add(1)
				go s.handleConnection(conn)
			}
		}()
	}

	return nil
}

// handleConnection 处理新的连接
func (s *BaseServer) handleConnection(conn net.Conn) {
	defer s.wg.Done()
	defer conn.Close()

	// 创建适配器
	adapter := NewNetConnAdapter(conn)

	// 创建会话
	session := NewSession(adapter, s.handler, NewDefaultAuthSource())

	// 创建带缓冲的读取器
	reader := bufio.NewReader(conn)

	// 处理会话
	if err := session.ProcessConnection(reader); err != nil {
		logger.LogError(session.ctx, "Session processing failed", "error", err)
	}
}

// Stop 停止服务器
func (s *BaseServer) Stop() error {
	if s.listener != nil {
		if err := s.listener.Close(); err != nil {
			return fmt.Errorf("error closing listener: %v", err)
		}
	}
	s.wg.Wait()
	return nil
}
